<template>
  <div>
<!-- 面包屑 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>权限管理</el-breadcrumb-item>
        <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>

<!-- 卡片视图 -->
    <el-card>
        <!-- 添加角色按钮区域 -->
        <el-row>
            <el-col>
                <el-button type="primary" @click='addiailogvisible=true'>添加角色</el-button>
            </el-col>
        </el-row>

        <!-- 角色列表区域 --> 
        <el-table :data='roleslist' border stripe>
            <!-- 展开列 -->
            <el-table-column type=expand>
                <template slot-scope="scope">
                    <el-row v-for="(item1,ind1) of scope.row.children" :key='item1.id' :class="['expand',ind1===0?'expand_top':'','display']">
                        <!-- 渲染一级权限 -->
                        <el-col :span='5'>
                            <el-tag closable @close='removerolesbyid(scope.row,item1.id)'>{{item1.authName}}</el-tag>
                            <i class="el-icon-caret-right"></i>
                        </el-col>
                        <!-- 渲染二级、三级权限 -->
                        <el-col :span='19'>
                            <!-- 通过for循环 嵌套渲染二级权限 -->
                            <el-row v-for="(item2,ind2) of item1.children" :key='item2.id' :class="[ind2===0?'':'expand_top','display']">
                                <!-- 渲染二级权限 -->
                                <el-col :span='6'>
                                    <el-tag type="success" closable @close='removerolesbyid(scope.row,item2.id)'>{{item2.authName}}</el-tag>
                                    <i class="el-icon-caret-right"></i>
                                </el-col>
                                <el-col :span='18'>
                                    <!-- 通过for循环，嵌套渲染三级权限 -->
                                    <el-tag type="warning" closable @close='removerolesbyid(scope.row,item3.id)'  v-for="(item3,ind3) of item2.children" :key='item3.id'>{{item3.authName}}</el-tag>
                                </el-col>
                            </el-row>
                        </el-col>
                    </el-row>
                    <!-- 标签pre用于美化页面 -->
                    <!-- <pre>{{scope.row}}</pre> -->
                </template>
            </el-table-column>
            <!-- 索引列 -->
            <el-table-column type='index'></el-table-column>
            <el-table-column label="角色名称" prop="roleName"></el-table-column>
            <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
            <el-table-column label="操作" prop="level" width="300px">
                <template slot-scope="scope">
                    <el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditDialog(scope.row.id)">编辑</el-button>
                    <el-button size="mini" type="danger" icon="el-icon-delete" @click='removerolesbyid(scope.row.id)'>删除</el-button>
                    <!-- 点击分配权限按钮时，立即获取当前权限的三级权限的所有id,保存到defkeys中， -->
                    <el-button size="mini" type="warning" icon="el-icon-setting" @click='showSetrightdialog(scope.row)'>分配权限</el-button>
                </template>
            </el-table-column>
        </el-table>
    </el-card>   

    <!-- 添加角色对话框 -->
    <el-dialog
        title="添加角色"
        :visible.sync="addiailogvisible"
        width="50%"
        @close='addclose'>
      <!-- 内容主体区域 -->
      <el-form :model="addrolesform" :rules='addformrules' ref="addformref" label-width="80px">
        <el-form-item label="角色名称" :hide-required-asterisk='true' prop="roleName">
          <el-input v-model="addrolesform.roleName"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDesc">
          <el-input v-model="addrolesform.roleDesc"></el-input>
        </el-form-item>
      </el-form>
        <!-- 底部按钮区域 -->
        <span slot="footer" class="dialog-footer">
            <el-button @click="addiailogvisible = false">取 消</el-button>
            <el-button type="primary" @click="addroles">确 定</el-button>
        </span>
    </el-dialog>

    <!-- 编辑角色对话框 -->
    <el-dialog
        title="编辑添加角色"
        :visible.sync="editdialogVisible"
        width="50%"
        @close='editlogclose'
       >
      <!-- 内容主体区域 -->
      <el-form :model="editform" :rules='editformrules' ref="editformref" label-width="80px">
        <el-form-item label="角色名称" :hide-required-asterisk='true' prop="roleName">
          <el-input v-model="editform.roleName"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDesc">
          <el-input v-model="editform.roleDesc"></el-input>
        </el-form-item>
      </el-form>
        <!-- 底部按钮区域 -->
        <span slot="footer" class="dialog-footer">
            <el-button @click="editdialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="editinfo()">确 定</el-button>
        </span>
    </el-dialog>

    <!-- 分配权限对话框 -->
    <el-dialog
        title="分配权限"
        :visible.sync="setdialogVisible"
        width="50%"
         @close='setclose'>
        
        <!-- 树形控件 -->
        <el-tree 
         :data="setrightdialoglist"
         :props="treeProps" 
         show-checkbox 
         node-key='id'
         default-expand-all
         :default-checked-keys='defkeys'
         ref='treeref'></el-tree>
        <span slot="footer" class="dialog-footer">
            <el-button @click="setdialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="allotrights">确 定</el-button>
        </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'roles',
  data(){
      return{
        //   角色列表
          roleslist:[],
        //   添加角色用户对话框显示隐藏
        addiailogvisible:false,
        // 编辑角色对话框显示隐藏
        editdialogVisible:false,
        // 分配权限对话框显示隐藏
        setdialogVisible:false,
        // 权限列表(树形tree)
        setrightdialoglist:[],
        // 树形控件属性绑定控件
        treeProps:{
            children:'children',
            label:'authName'
        },
        // 默认选中的节点id
        defkeys:[],
        // 当前即将分配权限的角色id
        roleid:'',
        // 添加角色表单数据对象
        addrolesform:{
            roleName:'',
            roleDesc:'',
        },
        // 查询到的角色信息数据对象
        editform:{},
        // 添加效验规则
        addformrules:{
            // 角色名称效验
            roleName:[
                {required:true,message:'请输入角色名称',trigger:'blur'},
                {min:2,max:12,message:'长度在2-12个字符',trigger:'blur'}
            ]
        },
        // 编辑角色规则
        editformrules:{
            // 角色名称效验
            roleName:[
                {required:true,message:'请输入角色名称',trigger:'blur'},
                {min:2,max:12,message:'长度在2-12个字符',trigger:'blur'}
            ]
        }
      }
  },
  methods:{
    //   获取角色列表
      async getroleslist(){
          const {data:res}=await this.$axios.get('/roles')
          if(res.meta.status!==200) return this.$message.error('获取角色列表失败')
          this.roleslist=res.data
          this.$message.success('获取角色列表成功')
      },
    //   监听 添加角色的关闭事件，重置表单
    addclose(){
        this.$refs.addformref.resetFields()
    },
    // 点击按钮，添加角色
    addroles(){
        //表单预验证
        this.$refs.addformref.validate(valid=>{
            if(!valid) return
            // 可以发送添加角色的网络请求
            this.$axios.post('/roles',this.addrolesform).then(res=>{
                if(res.data.meta.status!==201) return this.$message.error('添加角色失败')
                this.$message.success('添加角色成功')
                // 隐藏添加角色对话框
                this.addiailogvisible=false
                this.getroleslist()
            })
        })
    },
    // 展示修改角色对话框
    async showEditDialog(id){
        const {data:res}=await this.$axios.get('/roles/'+id)
        if(res.meta.status!==200) return this.$message.error('查询角色失败')
        this.editform=res.data;
        this.editdialogVisible=true
    },
    // 监听修改角色的关闭事件
    editlogclose(){
        // 重置表单
        this.$refs.editformref.resetFields()
    },
//   点击修改角色，并提交
    editinfo(){
        //表单预效验
        this.$refs.editformref.validate(valid=>{
            if(!valid) return
            // 发送修改角色的请求
            console.log(this.editform)
            this.$axios.put('/roles/'+this.editform.roleId,{
                roleName:this.editform.roleName,
                roleDesc:this.editform.roleDesc
            }).then(res=>{
                console.log(res)
                if(res.data.meta.status!==200) return this.$message.error('编剧角色失败')
                this.$message.success('编剧角色成功')
                // 隐藏对话框
                this.editdialogVisible=false
                // 重新查询角色列表
                this.getroleslist()
            })
        })
    },
    // 根据id删除当前角色
    removerolesbyid(id){
        // 弹框询问是否要执行此操作
        this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
            this.$axios.delete('/roles/'+id).then(res=>{
                if(res.data.meta.status!==200) return this.$message.error('删除角色失败')
                // 重新获取角色列表
                this.getroleslist()
                this.$message({
                    type: 'success',
                    message: '删除成功!'
                });
            })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });          
        });
    },
    // 根据id删除权限
    removerolesbyid(roleid,rightid){
        // 弹出是否要删除提示框
        this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
            this.$axios.delete(`roles/${roleid.id}/rights/${rightid}`).then(res=>{
                console.log(res)
                if(res.data.meta.status!==200) return this.$message.error('删除权限失败')
                this.$message({
                    type: 'success',
                    message: '删除权限成功!'
                });
                // 为防止删除权限后，展开行收起，不要使用，this.getroleslist()，
                // 在请求成功后，会返回新的权限列表
                // this.getroleslist()
                roleid.children=res.data.data
            })

        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });          
        });
    },
    // 展示分配权限的对话框
    async showSetrightdialog(role){
        // 将当前角色的id保存
        this.roleid=role.id
        const {data:res}=await this.$axios.get('/rights/tree')
        if(res.meta.status!==200) return this.$message.error('获取权限列表失败')
    //    把获取到的权限数据保存到Setrightdialoglist
       this.setrightdialoglist=res.data

    //    递归获取三级节点的id
        this.getlistdefkeys(role,this.defkeys)
        // 显示分配权限对话框
        this.setdialogVisible=true
    },
    // 通过递归的形式，获取角色下所有三级权限的id，并保存到 defkeys中
    getlistdefkeys(node,arr){
        // 如果当前 node 节点不包括 children 属性，则说明是三级节点
        if(!node.children) return arr.push(node.id)

        node.children.forEach(item => {
            this.getlistdefkeys(item,arr)
        });
    },
    // 监控分配角色弹出框的关闭事件，重置弹出框
    setclose(){
        // 重置数组
        this.defkeys=[] 
    },
    // 点击为角色分配权限
    allotrights(){
        const keys=[
            // 展开运算符...
            ...this.$refs.treeref.getCheckedKeys(),
            ...this.$refs.treeref.getHalfCheckedKeys()
        ]
        
        const idstr=keys.join(',')
        this.$axios.post(`roles/${this.roleid}/rights`,{rids:idstr}).then(res=>{
            if(res.data.meta.status!==200) return this.$message.error('分配权限失败')

            this.$message.success("分配权限成功")
            this.getroleslist()
            this.setdialogVisible=false
        })
    }
  },
  created(){
    //   获取角色列表
      this.getroleslist()
  },
}
</script>

<style lang="less" scoped>
.el-tag{
    margin:6px;
}
.expand{
    border-bottom: 1px solid #eee;
}

.expand_top{
    border-top: 1px solid #eee;
}
.display{
    display: flex;
    align-items: center;
}
</style>
